﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using ShevaEngine.Core.Interfaces;

namespace ShevaEngine.Core.Modules.Input
{
    /// <summary>
    /// Trida ovladace gamepad.
    /// </summary>
    public class ShevaGamepad : IUpdateAble
    {
        /// <summary>Player index.</summary>
        private PlayerIndex PlayerIndex;
        /// <summary>Predchozi stav.</summary>
        private GamePadState PreviousState;

        /// <summary>Udalost vyvolana klikem na tlacitko gamepadu.</summary>
        public event OnButtonDelegate OnButtonClick;
        /// <summary>Udalost vyvolana klikem na tlacitko gamepadu.</summary>
        public event OnButtonDelegate OnButtonDown;
        /// <summary>Udalost vyvolana klikem na tlacitko gamepadu.</summary>
        public event OnButtonDelegate OnButtonUp;

        /// <summary>
        /// Indikace pripojeni gamepadu.
        /// </summary>
        public bool IsConnected
        {
            get { return this.PreviousState.IsConnected; }
        }

        /// <summary>
        /// Orientace leve packy.
        /// </summary>
        public Vector2 LeftThumbStick
        {
            get { return this.PreviousState.ThumbSticks.Left; }
        }

        /// <summary>
        /// Orientace leve packy.
        /// </summary>
        public Vector2 RightThumbStick
        {
            get { return this.PreviousState.ThumbSticks.Right; }
        }

        /// <summary>
        /// Konstruktor.
        /// </summary>
        public ShevaGamepad(PlayerIndex index)
        {
            this.PlayerIndex = index;
            this.PreviousState = GamePad.GetState(this.PlayerIndex);
        }

        
        /// <summary>
        /// Metoda update.
        /// </summary>
        /// <param name="deltaT"></param>
        public void Update(GameTime time)
        {
            GamePadState state = GamePad.GetState(this.PlayerIndex);

            this.UpdateButton(state, Buttons.DPadUp);
            this.UpdateButton(state, Buttons.DPadDown);
            this.UpdateButton(state, Buttons.DPadLeft);
            this.UpdateButton(state, Buttons.DPadRight);
            this.UpdateButton(state, Buttons.Start);
            this.UpdateButton(state, Buttons.Back);
            this.UpdateButton(state, Buttons.LeftStick);
            this.UpdateButton(state, Buttons.RightStick);
            this.UpdateButton(state, Buttons.LeftShoulder);
            this.UpdateButton(state, Buttons.RightShoulder);
            this.UpdateButton(state, Buttons.BigButton);
            this.UpdateButton(state, Buttons.A);
            this.UpdateButton(state, Buttons.B);
            this.UpdateButton(state, Buttons.X);
            this.UpdateButton(state, Buttons.Y);
            this.UpdateButton(state, Buttons.LeftThumbstickLeft);
            this.UpdateButton(state, Buttons.RightTrigger);
            this.UpdateButton(state, Buttons.LeftTrigger);
            this.UpdateButton(state, Buttons.RightThumbstickUp);
            this.UpdateButton(state, Buttons.RightThumbstickDown);
            this.UpdateButton(state, Buttons.RightThumbstickRight);
            this.UpdateButton(state, Buttons.RightThumbstickLeft);
            this.UpdateButton(state, Buttons.LeftThumbstickUp);
            this.UpdateButton(state, Buttons.LeftThumbstickDown);
            this.UpdateButton(state, Buttons.LeftThumbstickRight);

            this.PreviousState = state;
        }

        /// <summary>
        /// Metoda updatuje button.
        /// </summary>
        /// <param name="state"></param>
        /// <param name="button"></param>
        private void UpdateButton(GamePadState state, Buttons button)
        {
            if (this.PreviousState.IsButtonDown(button) && state.IsButtonUp(button))
            {
                if (this.OnButtonUp != null)
                    this.OnButtonUp(this, button);
            }
            else
                if (this.PreviousState.IsButtonUp(button) && state.IsButtonDown(button))
                {
                    if (this.OnButtonClick != null)
                        this.OnButtonClick(this, button);

                    if (this.OnButtonDown != null)
                        this.OnButtonDown(this, button);
                }            
        }

        /// <summary>
        /// Metoda checkne tlacitko.
        /// </summary>
        /// <param name="button"></param>
        /// <param name="previousState"></param>
        /// <param name="newState"></param>
        public void CheckButton(Buttons button, ButtonState previousState, ButtonState newState)
        {

        }
    }

    /// <summary>
    /// Delegat udalosti vyvolana tacitkem mysi.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="button"></param>
    public delegate void OnButtonDelegate(object sender, Buttons button);
}
